/**
 * 
 */
package com.faxsun.core.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import mblog.core.persist.dao.CommentDao;
import mblog.core.persist.dao.UserDao;
import mblog.core.pojos.Comment;
import mblog.core.utils.BeanMapUtils;
import mtons.modules.pojos.Page;
import mtons.modules.pojos.UserContextHolder;
import mtons.modules.pojos.UserProfile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import com.faxsun.core.persist.entity.CommentPO;
import com.faxsun.core.service.CommentService;
import com.faxsun.core.service.LiveMsgService;
import com.faxsun.core.service.PostService;
import com.faxsun.core.service.TagService;

/**
 * @author langhsu
 *
 */
public class CommentServiceImpl implements CommentService {
	@Autowired
	private CommentDao commentDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private PostService postService;

	@Autowired
	private TagService tagService;
	
	@Autowired
	private LiveMsgService liveMsgService;
	
    private final static String CACHE = "CommentServiceCache";
    private final static Logger log = LoggerFactory.getLogger(CommentServiceImpl.class);

	@Override
	@Transactional(readOnly = true)
	public void paging(Page page, long toId, int type, int status) {
		List<CommentPO> list = commentDao.paging(page, toId, type, status);
		List<Comment> rets = new ArrayList<Comment>();
		for (CommentPO po : list) {
            Comment cmt = BeanMapUtils.copy(po);
			if(po.getContent().contains(CommentService.REPLY_TOKEN)){
			   String[] tmp = po.getContent().split(CommentService.REPLY_TOKEN);
			   cmt.setContent("回复" + tmp[1] + ":" + tmp[2]);    
			}
            rets.add(cmt);
		}
		page.setResults(rets);
	}

	@Override
	@Transactional
	@CacheEvict(value = CACHE, key = "'getCommentsFrom?toId='+#comment.toId+'&type='+#comment.type")
	public long post(Comment comment) {
		CommentPO po = new CommentPO();

		UserProfile up = UserContextHolder.getUserProfile();
		// Assert.notNull(up, "not login");
		//
		po.setAuthor(userDao.get(up.getId()));
		// po.setAuthor(userDao.get(1L));
		po.setToId(comment.getToId());
		po.setContent(comment.getContent());
		po.setCreated(new Date());
		po.setType(comment.getType());
		// skip status=0
		// FIXME: introduce review mechanism,here mark as published
		po.setStatus(1);
		commentDao.save(po);

		// 自增评论数
		if (comment.getType() == Comment.COMMENT_TO_POST) {
			postService.identityComments(po.getToId());
		} else if (comment.getType() == Comment.COMMENT_TO_PRODUCT) {
			tagService.identityComments(po.getToId());
		}else if(comment.getType()==Comment.COMMENT_TO_LIVE_MSG){
			liveMsgService.incrementComment(po.getToId());
		}
		return po.getId();
	}

	@Override
    @Cacheable(value = CACHE, key = "'getCommentsFrom?toId='+#toId+'&type='+#type")
	public long count(Long toId, int type) {
		return commentDao.count(toId, type);
	}

	@Override
	@Transactional
	public void delete(long id) {
		CommentPO comment = commentDao.get(id);
		if (comment != null) {
			commentDao.delete(id);
			int type = comment.getType();
			if (type == Comment.COMMENT_TO_POST) {
				postService.identityComments(comment.getToId(), -1);
			} else if (type == Comment.COMMENT_TO_PRODUCT) {
				tagService.identityComments(comment.getToId(), -1);
			}else if(comment.getType()==Comment.COMMENT_TO_LIVE_MSG){
				liveMsgService.decrementComment(comment.getToId());
			}
		}
	}

    @Override
    @Transactional(readOnly = true)
    public void pagingInbox(Page page, long userId, int status) {
        List<CommentPO> list = commentDao.pagingInbox(page, userId, status);
        List<Comment> rets = new ArrayList<Comment>();
        for (CommentPO po : list) {
            Comment cmt = BeanMapUtils.copy(po);
            cmt.setToUser(BeanMapUtils.copy(userDao.get(po.getToId())));
            if(po.getContent().contains(CommentService.REPLY_TOKEN)){
                String[] tmp = po.getContent().split(CommentService.REPLY_TOKEN);
                cmt.setContent(tmp[2]);
            }
            rets.add(cmt);            
        }
        page.setResults(rets);
    }

    @Override
    @Transactional
    @Cacheable(value = CACHE, key = "'getCommentsFrom?toId='+#toId+'&startId='+#startId+'&endId='+#endId+'&size='+#size+'&status='+#status")
    public List<Comment> getCommentsFrom(long toId, long startId, long endId, int size, List<Integer> types, int status, List<Long> blacklistAuthors) {
        List<CommentPO> list = commentDao.getCommentsFrom(toId, startId, endId, size, types, status, blacklistAuthors);
        log.info("retrieve live comment data from db size="+list.size());
        List<Comment> rets = new ArrayList<Comment>();
        for (CommentPO po : list) {
            Comment cmt = BeanMapUtils.copy(po);
            rets.add(cmt);
        }
        if(startId != -1 && endId == -1){
           Collections.sort(rets, Comment.Comparators.ID_DESC);            
        }
        return rets;
    }

    @Override
    @Transactional(readOnly = true)
    public long getMaxCommentIdFrom(long toId, int type, int status, List<Long> blacklistAuthors) {
        return commentDao.getMaxCommentIdFrom(toId, type, status, blacklistAuthors);
    }

}
